import { View } from '@tarojs/components';
import Taro from '@tarojs/taro';
import classNames from 'classnames';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import Mask, { BaseModalProps } from '../Mask';
import styles from './index.module.scss';

export interface BaseDialogProps extends BaseModalProps {
  position?: 'top' | 'right' | 'bottom' | 'left'
  children?: React.ReactNode,
  show: boolean,
  open?: () => void,
  opened?: () => void,
  close?: () => void,
  closed?: () => void,
  onMaskClick?: () => void
}

/**
 * Popup 组件
 * 用于展示一个弹出层组件，支持设置显示位置、动画效果以及蒙层点击行为。
 *
 * @param props BaseDialogProps 组件接收的props，继承自BaseDialogProps。
 *              包括：
 *              - show: 控制弹出层是否显示的布尔值。
 *              - children: 弹出层内容。
 *              - position: 弹出层的位置，默认为 bottom。
 *              - open: 弹出层打开时的回调函数。
 *              - opened: 弹出层完全显示后的回调函数。
 *              - close: 弹出层关闭时的回调函数。
 *              - closed: 弹出层完全关闭后的回调函数。
 *              - onMaskClick: 蒙层被点击时的回调函数。
 * @returns 返回一个包裹了弹出层内容和蒙层的JSX元素。
 */

const Popup = (props: BaseDialogProps) => {
  const {
    show, children, position = 'bottom', open, opened, close, closed, onMaskClick,
  } = props;

  const [display, setDisplay] = useState(false);
  const [showStyle, setShowStyle] = useState({});
  const wrapperRef = useRef<HTMLDivElement>(null);

  const barTop = useMemo(() => {
    const windowInfo = Taro.getWindowInfo();
    return windowInfo?.statusBarHeight || 0;
  }, []);

  const cls = classNames({
    [styles.popup]: true,
    [styles[`${position}-popup`]]: true,
    [styles[`${position}-show`]]: show,
    [styles[`${position}-hide`]]: !show,
  });

  useEffect(() => {
    if (show) {
      setDisplay(true);
    }
  }, [show]);

  useEffect(() => {
    const node = wrapperRef.current;
    if (display && node) {
      setShowStyle({
        paddingTop: position === 'bottom' ? '' : `${barTop}px`,
      });
    }
  }, [display]);

  const onAnimationStart = () => {
    show ? (open && open()) : (close && close());
  };

  const onAnimationEnd = () => {
    if (!show) {
      setDisplay(false);
    }
    show ? (opened && opened()) : (closed && closed());
  };

  return <Mask show={show} onMaskClick={onMaskClick}>
    {display ?
      <View ref={wrapperRef} className={cls} onAnimationStart={() => onAnimationStart()}
            onAnimationEnd={() => onAnimationEnd()} style={showStyle}
      >{children}</View> : null}
  </Mask>;
};

export default Popup;
